package com.hyper_yang._04_jvm.chap06;

import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;

/**
 * 虚引用：    虚引用关联的对象是不能通过虚引用get()方法获取的；虚引用关联对象时，结合引用对象ReferenceQueue；当虚引用关联对象被GC了。那么，引用对象中会存储虚引用对象。
 */
public class PhantomReferenceTest {

    public static void main(String[] args) throws InterruptedException {
        User obj = new User(1, "zhangsan");
        ReferenceQueue<Object> queue = new ReferenceQueue<>();
        PhantomReference<Object> phantomRef = new PhantomReference<>(obj, queue);
        System.out.println("phantomRef = " + phantomRef);
        obj = null; // 解除强引用

        // 在这里，对象可能已经被垃圾回收了，但我们无法通过虚引用获取它

        // 判断虚引用是否被回收
        boolean isCollected = false;
        while (!isCollected) {
            System.gc(); // 建议垃圾回收器执行回收操作
            try {
                Thread.sleep(1000); // 等待1秒钟
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (phantomRef.isEnqueued()) { //判断虚引用是否已经被回收。
                isCollected = true;
            }
        }
        //Object object = phantomRef.get();
        //System.out.println("object = " + object);
        PhantomReference<Object> ref = (PhantomReference<Object>) queue.remove(); //阻塞方法。 队列为空，一直阻塞在这。
        System.out.println("ref = " + ref);
        // 输出虚引用是否被回收
        System.out.println("虚引用是否被回收：" + isCollected);
    }
}